Return to start page

Systems/Character/Struct Info.j

Code

		
1			library AStructSystemsCharacterInfo requires optional ALibraryCoreDebugMisc, ALibraryCoreEnvironmentSound, ALibraryCoreGeneralPlayer, AStructCoreInterfaceThirdPersonCamera, ALibraryCoreInterfaceCinematic, ALibraryCoreInterfaceMisc, ALibraryCoreMathsUnit, AStructSystemsCharacterVideo
2
3
4 /**
5 * Methods are often called in their own threads -> TriggerSleepAction problem.
6 */
7 function speech takes AInfo info, boolean toCharacter, string text, sound usedSound returns nothing
8 local real duration
9 local player user = info.talk().character().user()
10 local unit speaker
11 local unit listener
12 local player speakerOwner
13 call waitForVideo(1.0) // do not show any speeches during video
14 if (toCharacter) then
15 set speaker = info.talk().unit()
16 set listener = info.talk().character().unit()
17 set speakerOwner = GetOwningPlayer(info.talk().unit())
18 else
19 set speaker = info.talk().character().unit()
20 set listener = info.talk().unit()
21 set speakerOwner = info.talk().character().user()
22 endif
23 if (usedSound != null) then
24 set duration = GetSoundDurationBJ(usedSound)
25 else
26 set duration = bj_NOTHING_SOUND_DURATION
27 endif
28 if (AInfo.speechAnimation != null) then
29 call SetUnitAnimation(speaker, AInfo.speechAnimation)
30 endif
31 if (AInfo.listenAnimation != null) then
32 call SetUnitAnimation(listener, AInfo.listenAnimation)
33 endif
34 if (usedSound != null) then
35 call PlaySoundForPlayer(user, usedSound)
36 endif
37 /*
38 call CameraSetupApplyForPlayer(false, AInfo.cameraSetup, user, 0.0)
39 call SetCameraFieldForPlayer(user, CAMERA_FIELD_ROTATION, GetUnitFacing(speaker) - 180.0, 0.0)
40 call SetCameraFieldForPlayer(user, CAMERA_FIELD_ZOFFSET, GetUnitZ(speaker) + 128.0, 0.0)
41 call SetCameraTargetControllerNoZForPlayer(user, speaker, 0.0, 0.0, false)
42 */
43 call AThirdPersonCamera.playerThirdPersonCamera(user).enable(listener, 0.0)
44 call SetCinematicSceneForPlayer(user, GetUnitTypeId(speaker), speakerOwner, GetUnitName(speaker), text, duration, duration)
45 if (info.talk().character().talkLog() != 0) then
46 call info.talk().character().talkLog().addMessage(info.talk(), text) //log message
47 endif
48 call waitForVideo(1.0) // do not show any speeches during video
49 if (AInfo.skipKey == -1) then
50 call TriggerSleepAction(duration)
51 else
52 set AInfo.playerHasSkipped[GetPlayerId(user)] = false
53 loop
54 exitwhen (duration <= 0.0)
55 if (AInfo.playerHasSkipped[GetPlayerId(user)]) then
56 //if (AInfo.skipKey != KEY_ESCAPE) then
57 //call ClearScreenMessagesForPlayer(user) /// @todo Does not do anything.
58 //endif
59 set AInfo.playerHasSkipped[GetPlayerId(user)] = false
60 return
61 endif
62 call TriggerSleepAction(AInfo.skipCheckRate)
63 set duration = duration - AInfo.skipCheckRate
64 endloop
65 endif
66 call StopSound(usedSound, true, false) //stop sound since speech could have been skipped by player
67 call ResetUnitAnimation(speaker)
68 call ResetUnitAnimation(listener)
69 call AThirdPersonCamera.playerThirdPersonCamera(user).disable()
70 set user = null
71 set speaker = null
72 set listener = null
73 set speakerOwner = null
74 endfunction
75
76 /// @todo Shoud be a static member of @struct AInfo, vJass bug.
77 function interface AInfoCondition takes AInfo info returns boolean
78
79 /// @todo Shoud be a static member of @struct AInfo, vJass bug.
80 function interface AInfoAction takes AInfo info returns nothing
81
82 /**
83 * Members of talks are called informations or infos. An info is a single object which informs
84 * the user about something like new quests or important things which happened.
85 * Infos can have their own condition, so player do not always get access to them.
86 * This allows the creator to write nice multiple choice dialogs for different classes or players.
87 * Additionally you're able to make infos permanent, so player can always use or get them if the condition is true.
88 * Since there probably will be some longer speeches of an information they're skipable by pressing a specific key.
89 * This must be explicit enabled when calling the struct initializer (@method AInfo.init).
90 */
91 struct AInfo
92 //static start members
93 public static camerasetup cameraSetup /// Do not use.
94 public static integer skipKey /// Do not use.
95 public static real skipCheckRate /// Do not use.
96 public static string speechAnimation /// Do not use.
97 public static string listenAnimation /// Do not use.
98 //static members
99 private static trigger skipTrigger
100 public static boolean array playerHasSkipped[12] //bj_MAX_PLAYERS /// Do not use.
101 //start members
102 private ATalk m_talk
103 private boolean m_permanent
104 private boolean m_important
105 private AInfoCondition m_condition
106 private AInfoAction m_action
107 private string m_description
108 //members
109 private ADialogButton m_dialogButton
110 private integer m_talkIndex
111 private boolean array m_hasBeenShownToCharacter[12] //bj_MAX_PLAYERS
112
113 //! runtextmacro optional A_STRUCT_DEBUG("\"AInfo\"")
114
115 //start members
116
117 public method talk takes nothing returns ATalk
118 return this.m_talk
119 endmethod
120
121 public method permanent takes nothing returns boolean
122 return this.m_permanent
123 endmethod
124
125 public method important takes nothing returns boolean
126 return this.m_important
127 endmethod
128
129 public method condition takes nothing returns AInfoCondition
130 return this.m_condition
131 endmethod
132
133 public method action takes nothing returns AInfoAction
134 return this.m_action
135 endmethod
136
137 public method description takes nothing returns string
138 return this.m_description
139 endmethod
140
141 //members
142
143 public method isShown takes nothing returns boolean
144 return this.m_dialogButton != 0
145 endmethod
146
147 public method dialogButtonIndex takes nothing returns integer
148 return this.m_dialogButton.index()
149 endmethod
150
151 public method hasBeenShownToCharacter takes integer playerId returns boolean
152 return this.m_hasBeenShownToCharacter[playerId]
153 endmethod
154
155 //methods
156
157 private static method dialogButtonActionRunInfo takes ADialogButton dialogButton returns nothing
158 local ATalk talk = ACharacter.playerCharacter(dialogButton.dialog().player()).talk()
159 local thistype info = talk.getInfoByDialogButtonIndex(dialogButton.index())
160 call talk.clear()
161 call info.run()
162 endmethod
163
164 public method show takes nothing returns boolean
165 local unit self = this.m_talk.character().unit()
166 local player user = this.m_talk.character().user()
167 local integer shortcut
168 local boolean result = false
169 if (this.m_permanent or not this.m_hasBeenShownToCharacter[GetPlayerId(user)]) then
170 if (this.m_important) then
171 if (this.m_condition == 0 or this.m_condition.evaluate(this)) then
172 set result = true
173 call this.run()
174 endif
175 else
176 if (this.m_condition == 0 or this.m_condition.evaluate(this)) then
177 set result = true
178 set shortcut = AGui.playerGui(user).dialog().dialogButtons()
179 set this.m_dialogButton = AGui.playerGui(user).dialog().addDialogButton("[" + I2S(shortcut) + "] " + this.m_description, AShortcut0 + shortcut, thistype.dialogButtonActionRunInfo)
180 endif
181 endif
182 endif
183 set self = null
184 set user = null
185 return result
186 endmethod
187
188 public method hide takes nothing returns nothing
189 set this.m_dialogButton = 0
190 endmethod
191
192 public method run takes nothing returns nothing
193 local unit self = this.m_talk.character().unit()
194 local player user = GetOwningPlayer(self)
195 set this.m_hasBeenShownToCharacter[GetPlayerId(user)] = true
196 call this.m_action.execute(this)
197 set self = null
198 set user = null
199 endmethod
200
201 public static method create takes ATalk talk, boolean permanent, boolean important, AInfoCondition condition, AInfoAction action, string description returns AInfo
202 local AInfo this = AInfo.allocate()
203 //start members
204 set this.m_talk = talk
205 set this.m_permanent = permanent
206 set this.m_important = important
207 set this.m_condition = condition
208 set this.m_action = action
209 set this.m_description = description
210 //members
211 set this.m_dialogButton = 0
212 set this.m_talkIndex = talk.addInfoInstance(this)
213 return this
214 endmethod
215
216 public method onDestroy takes nothing returns nothing
217 call this.m_talk.removeInfoInstanceByIndex(this.m_talkIndex)
218 endmethod
219
220 private static method triggerConditionSkip takes nothing returns boolean
221 local player triggerPlayer = GetTriggerPlayer()
222 local boolean result = ACharacter.playerCharacter(triggerPlayer).talk() != 0
223 debug if (result) then
224 debug call AInfo.staticPrint("Result of info skip is true.")
225 debug endif
226 set triggerPlayer = null
227 return result
228 endmethod
229
230 private static method triggerActionSkip takes nothing returns nothing
231 local player triggerPlayer = GetTriggerPlayer()
232 //call ClearScreenMessagesForPlayer(triggerPlayer) //does not do anything
233 set AInfo.playerHasSkipped[GetPlayerId(triggerPlayer)] = true
234 /// @todo Stop sound immediatly
235 set triggerPlayer = null
236 endmethod
237
238 private static method createSkipTrigger takes nothing returns nothing
239 local integer i
240 local player user
241 local event triggerEvent
242 local conditionfunc conditionFunction
243 local triggercondition triggerCondition
244 local triggeraction triggerAction
245 set AInfo.skipTrigger = CreateTrigger()
246 set i = 0
247 loop
248 exitwhen (i == bj_MAX_PLAYERS)
249 set user = Player(i)
250 if (IsPlayerPlayingUser(user)) then
251 set triggerEvent = TriggerRegisterKeyEventForPlayer(user, AInfo.skipTrigger, AInfo.skipKey, true)
252 set triggerEvent = null
253 endif
254 set user = null
255 set i = i + 1
256 endloop
257 set conditionFunction = Condition(function AInfo.triggerConditionSkip)
258 set triggerCondition = TriggerAddCondition(AInfo.skipTrigger, conditionFunction)
259 set triggerAction = TriggerAddAction(AInfo.skipTrigger, function AInfo.triggerActionSkip)
260 set conditionFunction = null
261 set triggerCondition = null
262 set triggerAction = null
263 endmethod
264
265 public static method init takes camerasetup cameraSetup, integer skipKey, real skipCheckRate, string speechAnimation, string listenAnimation returns nothing
266 //static start members
267 set AInfo.cameraSetup = cameraSetup
268 set AInfo.skipKey = skipKey
269 set AInfo.skipCheckRate = skipCheckRate
270 if (skipKey != -1) then
271 call AInfo.createSkipTrigger()
272 endif
273 set AInfo.speechAnimation = speechAnimation
274 set AInfo.listenAnimation = listenAnimation
275 endmethod
276
277 public static method cleanUp takes nothing returns nothing
278 call DestroyTrigger(AInfo.skipTrigger)
279 set AInfo.skipTrigger = null
280 endmethod
281 endstruct
282
283 endlibrary